package com.maimao.goods.service;

import com.google.common.collect.Lists;
import com.maimao.core.model.resp.Result;
import com.maimao.core.utils.BigDecimalUtils;
import com.maimao.core.utils.MapUtils;
import com.maimao.goods.client.CouponClient;
import com.maimao.goods.client.UserClient;
import com.maimao.goods.mapper.GoodsSkuMapper;
import com.maimao.model.cart.ShoppingCart;
import com.maimao.model.goods.GoodsSku;
import com.maimao.model.info.input.ConfirmCoupon;
import com.maimao.model.order.confirm.ConfirmOrder;
import com.maimao.model.order.confirm.CouponSimple;
import com.maimao.model.order.confirm.vo.ConfirmOrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author MaoLin Wang
 * @date 2021/1/15 2:49 下午
 */
@Service
public class OrderService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private CouponClient couponClient;

    @Autowired
    private UserClient userClient;

    @Autowired
    private GoodsSkuMapper goodsSkuMapper;

    public Result generateConfirmOrder(List<Long> shoppingCartIdList, Long userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").in(shoppingCartIdList));
        List<ShoppingCart> shoppingCarts = mongoTemplate.find(query, ShoppingCart.class);
        if (shoppingCarts == null || shoppingCarts.size() <= 0 || shoppingCarts.size() != shoppingCartIdList.size()) {
            return Result.notValid("购物车记录不存在，请重新添加购物车");
        }
        ConfirmOrderVo vo = new ConfirmOrderVo();

        List<ConfirmOrder> confirmOrders = new ArrayList<>();

        checkGoodsValid(shoppingCarts, confirmOrders, userId);

        //当前订单总额
        BigDecimal orderTotalPrice = new BigDecimal(0);
        for (ConfirmOrder confirmOrder : confirmOrders) {
            for (ShoppingCart goods : confirmOrder.getGoodsList()) {
                orderTotalPrice = orderTotalPrice.add(goods.getTotalPrice());
            }
        }
        //领取并返回系统可用优惠券
        Result<List<CouponSimple>> usefulShopCouponRes = couponClient.takeAndQuerySysUsefulShopCoupon(
                ConfirmCoupon.builder()
                        .limit(orderTotalPrice)
                        .userId(userId)
                        //暂时没用
                        .specAreaIds(null)
                        .build());
        Result<Integer> integerResult = userClient.queryUserIntegral(String.valueOf(userId));
        if (integerResult != null && integerResult.getData() != null && integerResult.getData() >= 0) {
            vo.setIntegral(integerResult.getData());
        } else {
            vo.setIntegral(0);
        }
        if (usefulShopCouponRes != null && usefulShopCouponRes.getData() != null) {
            vo.setSysCouponList(usefulShopCouponRes.getData());
        }
        vo.setConfirmOrderList(confirmOrders);
        return Result.okData(vo);
    }

    /**
     * 校验已选商品的库存和有效性 将确认订单列表封装到 @param confirmOrders
     *
     * @param shoppingCarts 提交的购物车数据
     * @param confirmOrders 确认订单列表
     */
    private void checkGoodsValid(List<ShoppingCart> shoppingCarts, List<ConfirmOrder> confirmOrders, Long userId) {
        Map<Long, ShoppingCart> skuNumMap = new HashMap<>();
        shoppingCarts.stream().forEach(shoppingCart -> skuNumMap.put(shoppingCart.getSkuId(), shoppingCart));

        //购物车数据按店铺分组
        Map<Long, List<ShoppingCart>> shopGroup = shoppingCarts.stream().collect(Collectors.groupingBy(ShoppingCart::getShopId));

        ArrayList<Long> skuIds = Lists.newArrayList(skuNumMap.keySet());
        List<GoodsSku> goodsSkus = goodsService.querySkusByIdBatch(skuIds);

        if (goodsSkus == null || goodsSkus.size() <= 0) {
            return;
        }
        Map<Long, GoodsSku> goodsSkuMap = new HashMap<>(MapUtils.initCapacity(goodsSkus.size()));
        for (GoodsSku sku : goodsSkus) {
            goodsSkuMap.put(sku.getId(), sku);
        }

        ConfirmOrder confirmOrder = null;
        for (Map.Entry<Long, List<ShoppingCart>> entry : shopGroup.entrySet()) {
            List<ShoppingCart> shopGoods = entry.getValue();
            List<Long> shopGoodsIds = shopGoods.stream().map(ShoppingCart::getGoodsId).collect(Collectors.toList());

            confirmOrder = new ConfirmOrder();
            confirmOrder.setShopId(entry.getKey());
            confirmOrder.setShopName(shopGoods.get(0).getShopName());

            //店铺商品总额
            BigDecimal shopTotalPrice = BigDecimalUtils.defaultRounding(0, 2);
            for (ShoppingCart shopGood : shopGoods) {
                GoodsSku goodsSku = goodsSkuMap.get(shopGood.getSkuId());
                //判断库存
                if ((goodsSku.getStock() < shopGood.getNum()) || goodsSku.getValid().equals(0)) {
                    shopGood.setValid(false);
                } else {
                    shopGood.setValid(true);
                }
                Map<String, Object> brandIntegralMap = goodsSkuMapper.selectBrandIdAndSkuIntegralBySkuId(shopGood.getSkuId());
                Boolean giveIntegral = (Boolean) brandIntegralMap.get("give_integral");

                shopGood.setBrandId((Long) brandIntegralMap.get("brand_id"));
                shopGood.setGiveIntegral(giveIntegral == null ? false : giveIntegral);
                shopGood.setPrice(goodsSku.getPrice());
                shopGood.setTotalPrice(shopGood.getPrice().multiply(BigDecimal.valueOf(shopGood.getNum())));
                shopTotalPrice = shopTotalPrice.add(shopGood.getTotalPrice());
            }
            confirmOrder.setGoodsList(shopGoods);

            ConfirmCoupon confirmCoupon = ConfirmCoupon.builder().limit(shopTotalPrice)
                    .shopId(confirmOrder.getShopId())
                    .goodsId(shopGoodsIds)
                    .userId(userId)
                    .build();

            //领取当前店铺的可用优惠券并返回可用优惠券列表
            Result<List<CouponSimple>> usefulShopCouponRes = couponClient.takeAndQueryUsefulShopCoupon(confirmCoupon);
            if (usefulShopCouponRes != null && usefulShopCouponRes.getData() != null) {
                List<CouponSimple> data = usefulShopCouponRes.getData();
                confirmOrder.setCouponList(data);
            }
            confirmOrders.add(confirmOrder);
        }
    }
}
